package main

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"time"
)

// AccountData 结构保持不变
type AccountData struct {
	OutUid     string                 `json:"out_uid"`
	Type       int                    `json:"type"`
	Phone      string                 `json:"phone"`
	Email      string                 `json:"email"`
	Department string                 `json:"department"`
	OriginData map[string]interface{} `json:"originData"`
}

// 调整请求体结构
type RequestPayload struct {
	SourceCode string        `json:"source_code"`
	Data       []AccountData `json:"data"`
}

// 增强响应结构兼容性
type ApiResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    struct {
		SuccessUIDs []string `json:"success_uids"`
		FailedUIDs  []string `json:"failed_uids"`
	} `json:"data"`
}

func main() {
	// 初始化失败记录
	var failedUIDs []string
	client := createHTTPClient()

	// 遍历处理分片文件
	fileCounter := 1
	for {
		filename := fmt.Sprintf("%d.json", fileCounter)
		if _, err := os.Stat(filename); os.IsNotExist(err) {
			if fileCounter == 48 {
				break

			}
			fileCounter++
			continue

		}

		// 处理单个文件
		if err := processFile(client, filename, &failedUIDs); err != nil {
			fmt.Printf("处理文件 %s 时遇到问题: %v\n", filename, err)
		}

		fileCounter++
	}

	// 保存最终结果
	if err := saveResults(failedUIDs); err != nil {
		fmt.Printf("结果保存失败: %v\n", err)
	}
	fmt.Println("\n处理完成！失败UID数量:", len(failedUIDs))
}

func createHTTPClient() *http.Client {
	return &http.Client{
		Transport: &http.Transport{
			MaxIdleConns:       10,
			IdleConnTimeout:    60 * time.Minute,
			DisableCompression: true,
		},
		Timeout: 60 * time.Minute,
	}
}

func processFile(client *http.Client, filename string, failedUIDs *[]string) error {
	fmt.Printf("\n▶ 开始处理文件: %s\n", filename)

	// 读取并解析分片数据
	fileData, err := parseFileData(filename)
	if err != nil {
		return err
	}

	// 构造完整请求体
	payload := RequestPayload{
		SourceCode: "lx_msi",
		Data:       fileData,
	}

	// 发送请求并处理响应
	respData, err := sendRequest(client, payload)
	if err != nil {
		return err
	}

	// 收集失败UID
	*failedUIDs = append(*failedUIDs, respData.Data.FailedUIDs...)
	fmt.Printf("✅ 处理完成 | 成功: %d | 失败: %d\n",
		len(respData.Data.SuccessUIDs),
		len(respData.Data.FailedUIDs))

	return nil
}

func parseFileData(filename string) ([]AccountData, error) {
	fileContent, err := os.ReadFile(filename)
	if err != nil {
		return nil, fmt.Errorf("文件读取失败: %w", err)
	}

	var accounts []AccountData
	if err := json.Unmarshal(fileContent, &accounts); err != nil {
		return nil, fmt.Errorf("数据解析失败: %w", err)
	}

	fmt.Printf("发现 %d 条待处理数据\n", len(accounts))
	return accounts, nil
}

func sendRequest(client *http.Client, payload RequestPayload) (*ApiResponse, error) {
	// 序列化请求体
	requestBody, err := json.Marshal(payload)
	if err != nil {
		return nil, fmt.Errorf("请求体构造失败: %w", err)
	}

	// 创建带超时的请求
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	req, err := http.NewRequestWithContext(
		ctx,
		"POST",
		"https://cgate.xiaoduoai.com/openapi/en/out_auth/account_pull",
		bytes.NewReader(requestBody),
	)
	if err != nil {
		return nil, fmt.Errorf("请求创建失败: %w", err)
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJlbnRlcnByaXNlIiwiYXVkIjoiNjgxZGFiNjhlZTZjYzIwMDAxMWI2ZTE5IiwiaWF0IjoxNzQ1ODA2NzU5LCJleHAiOjE3NjU5OTMzMDV9.gsuYk6dAwnaupm3uaqsYLWzlatcILBWjYZSIvuaAFsQ")
	req.Header.Set("Accept-Encoding", "gzip")
	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("网络请求失败: %w", err)
	}
	defer resp.Body.Close()

	// 读取响应
	body, _ := io.ReadAll(resp.Body)
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("异常响应[%d]: %s", resp.StatusCode, string(body))
	}

	// 解析响应
	var apiResp ApiResponse
	if err := json.Unmarshal(body, &apiResp); err != nil {
		return nil, fmt.Errorf("响应解析失败: %s", string(body))
	}

	return &apiResp, nil
}

func saveResults(uids []string) error {
	// 去重处理
	uidMap := make(map[string]struct{})
	for _, uid := range uids {
		uidMap[uid] = struct{}{}
	}

	// 生成最终列表
	uniqueUIDs := make([]string, 0, len(uidMap))
	for uid := range uidMap {
		uniqueUIDs = append(uniqueUIDs, uid)
	}

	// 写入文件
	file, err := os.Create("failed_uids.json")
	if err != nil {
		return err
	}
	defer file.Close()

	encoder := json.NewEncoder(file)
	encoder.SetIndent("", "  ")
	return encoder.Encode(uniqueUIDs)
}
